枚举类序列化与反序列化
枚举默认按 name() 序列化、反序列化("SUCCESS" ↔ Status.SUCCESS)。实际接口里更常见的是用数字 code 或自定义字符串传输,靠 @JsonValue / @JsonCreator 控制。
指定序列化输出值:@JsonValue
@JsonValue 标在字段或无参方法上,序列化时输出它的值。标在字段上时,该字段值就是 JSON 值:
public enum Status {
SUCCESS(1),
FAILURE(0);
@JsonValue
final int code;
Status(int code) {
this.code = code;
}
}
// 序列化 Status.SUCCESS → 1
也可以标在方法上,@JsonValue public int getCode() { return code; },效果一样。
指定反序列化方法:@JsonCreator
反序列化用 @JsonCreator 标一个静态工厂方法,入参对应序列化输出的值类型。这样 1 能还原成 Status.SUCCESS:
public enum Status {
SUCCESS(1),
FAILURE(0);
@JsonValue
final int code;
Status(int code) {
this.code = code;
}
@JsonCreator
public static Status resolve(Integer code) {
if (code == null) {
return null;
}
for (Status e : values()) {
if (e.code == code) {
return e;
}
}
return null;
}
}
@JsonValue 与 @JsonCreator 配合,序列化输出 code、反序列化按 code 还原,收发对称。
处理未知值
JSON 传了个枚举里没有的值,默认反序列化直接抛异常。给某个枚举项标 @JsonEnumDefaultValue,匹配不到时回落到它,避免接口直接 500:
public enum Status {
SUCCESS(1),
FAILURE(0),
@JsonEnumDefaultValue
UNKNOWN(-1);
...
}
枚举项别名
一个枚举值想接受多个 JSON 输入(兼容大小写、新旧命名),用 @JsonProperty 给枚举项起别名:
public enum Status {
@JsonProperty("success") SUCCESS,
@JsonProperty("failure") FAILURE
}
此时 SUCCESS 序列化输出 "success","success" / "SUCCESS" 都能反序列化成 SUCCESS。